package com.btcode.netty.server.handler.hrt;

import com.btcode.common.ByteUnit;
import com.btcode.netty.server.handler.AbstractHrtDecoder;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;

import java.util.List;

public class WaterSupplyDecoder extends AbstractHrtDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        try {
            //从站编号加上数据长度，必须有3位
            if (in.readableBytes() < 3) {
                log.info("数据长度不够");
                return;
            }

            in.markReaderIndex();
            int readIndex = in.readerIndex();
            byte[] mnByte = new byte[1];
            in.getBytes(readIndex, mnByte);

            int mn = ByteUnit.ConvertByteToInt8(mnByte[0]);
            String msg = getByteBufHexStr(in);

            if (mn <= 0) {
                //设备编号不会小于零
                log.error("解析设备编号失败，编号不能小于0:" + msg);
                in.clear();
                return;
            }
            System.out.println("设备编号：" + mn);
            byte[] dataLengthByte = new byte[1];
            in.getBytes(readIndex + 2, dataLengthByte);

            if (dataLengthByte[0] == 0) {
                // 如果长度为0 说明是心跳包
                ByteBuf channelBuffer = in.readBytes(3);
                log.info(mn + "收到新心跳包");
                return;
            }

            if ((dataLengthByte[0] & 0xff) < 0) {
                log.error(mn + "长度为负数:" + msg);
                in.clear();
                return;
            }
            System.out.println("数据长度：" + dataLengthByte[0]);
            int expectDataLength = 1 + 1 + 1 + (dataLengthByte[0] & 0xff) + 2;//1位从站编号，1位功能码，1位数据长度，n位数据，2位校验位
            if (in.readableBytes() < expectDataLength) {
                //获取的数据长度和期望的长度不匹配，说明数据还没有接受完整，返回null等待数据
                log.info(mn + "数据长度不够，期望：" + expectDataLength + "，实际：" + in.readableBytes());
                in.resetReaderIndex();
            }
            else {
                System.out.println(mn + "收到数据:" + expectDataLength);
                out.add(in.readBytes(expectDataLength));
                ReferenceCountUtil.release(in);
            }
        }
        catch (Exception e) {
            log.error("报文粘拆包处理出错:" + getByteBufHexStr(in), e);
        }
    }

    @Override
    public String getMnFromChannel(ChannelHandlerContext ctx, ByteBuf msgDecodeOut) {
        return String.valueOf(ByteUnit.ConvertByteToInt8(getByteBufBytes(msgDecodeOut)[0]));
    }

    @Override
    public boolean[] shouldCheckConflictAndUseNewConn() {
        return new boolean[]{true, false};
    }
}
